package com.he.handler;

import com.he.domain.Result;
import com.he.exception.ServiceException;
import com.he.utils.AuthExceptionUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

import static com.he.enums.StatusCodeEnum.*;

/**
 * @author He
 * @version 1.0
 * @Date 2023/9/7 9:49
 * @Desc 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理业务异常
     */
    @ExceptionHandler(value = ServiceException.class)
    public Result<?> handleServiceException(ServiceException e) {
        return Result.fail(e.getMessage());
    }

    /**
     * 处理Assert异常
     */
    @ExceptionHandler(value = IllegalArgumentException.class)
    public Result<?> handleIllegalArgumentException(IllegalArgumentException e) {
        return Result.fail(e.getMessage());
    }

    /**
     * 处理参数校验异常(@Valid)
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        return Result.fail(VALID_ERROR.getCode(), Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }


    /**
     * 处理非法JSON格式异常
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public Result<?> handleHttpMessageNotReadable(HttpMessageNotReadableException ex) {
        return Result.fail(JSON_FORMAT_ERROR.getCode(), JSON_FORMAT_ERROR.getMsg());
    }

    /**
     * 处理权限异常
     */
    @ExceptionHandler(value = AccessDeniedException.class)
    public Result<?> handleAccessDeniedException(AccessDeniedException accessDeniedException) {
       return AuthExceptionUtil.getAccessExceptionType(accessDeniedException);
    }

    /**
     * 处理认证异常
     */
    @ExceptionHandler(value = AuthenticationException.class)
    public Result<?> handleAuthenticationException(AuthenticationException authException) {
        return AuthExceptionUtil.getAuthExceptionType(authException);
    }


    /**
     * 未登录异常
     */
    @ExceptionHandler(value = InsufficientAuthenticationException.class)
    public Result<?> handleInsufficientAuthenticationException(InsufficientAuthenticationException insufficientAuthenticationException) {
        return AuthExceptionUtil.getAuthExceptionType(insufficientAuthenticationException);
    }


    /**
     * 处理系统异常
     */
    @ExceptionHandler(value = Exception.class)
    public Result<?> handleSystemException(Exception e) {
        e.printStackTrace();
        return Result.fail(SYSTEM_ERROR.getCode(), SYSTEM_ERROR.getMsg());
    }


}
